#pragma once
#include "Sock.hpp"
#include<iostream>
#include <pthread.h>
#include <string>
#include<vector>
#include<functional>
#include<unistd.h>

namespace ns_tcpserver
{
    typedef std::function<void(int)>func_t;
    class TcpServer;
    class ThreadData
    {
    public: 
        ThreadData(){}
        ThreadData(int sock,TcpServer* server)
        :_sock(sock)
        ,_server(server)
        {

        }
    public:
        int _sock;
        TcpServer* _server;
    };
    class TcpServer 
    {
    public:
        TcpServer(const uint16_t& port,const std::string& ip="0.0.0.0")
        {
            _serversock=_sock.Socket();
            _sock.Bind(_serversock, port);
            _sock.Listen(_serversock);
        }

        // TcpServer(const uint16_t& port,const std::string& ip="0.0.0.0")
        // {
        //     _serversock=_sock.Socket();
        //     _sock.Bind(_serversock, port,ip);
        //     _sock.Listen(_serversock);
        // }
        void BindHandler(func_t callback)
        {
            _funcs.push_back(callback);
        }
        // void BindHandler(func_t callback)
        // {
        //     _funcs.push_back(callback);
        // }
        void Execute(int sock)
        {
            for(auto& iter:_funcs)
            {
                iter(sock);
            }
        }
        // void Execute(int sock)
        // {
        //     for(auto& iter:_funcs){
        //         iter(_serversock);
        //     }
        // }
        // void Start()
        // {
        //     while(true)
        //     {
        //         std::string client_ip;
        //         uint16_t client_port;
        //         //每一个线程要执行不同的任务，监听sock接受到了一个新的sock
        //         int sock=_sock.Accept(_serversock, &client_port, &client_ip);
        //         if(sock == -1){
        //             continue;
        //         }
        //         pthread_t tid;
        //         ThreadData* td=new ThreadData(sock,this);
        //         pthread_create(&tid, nullptr, ThreadRoutine, (void*)td);
        //     }
        // }
        void Start()
        {
            while(true)
            {
                std::string client_ip;
                uint16_t client_port;
                int sock=_sock.Accept(_serversock, &client_port, &client_ip);
                if(sock == -1){
                    continue;
                }
                ThreadData* td=new ThreadData(sock,this);
                pthread_t tid;
                pthread_create(&tid, nullptr, ThreadRoutine, (void*)td);
            }
        }
        ~TcpServer(){
            if(_serversock >= 0){
                close(_serversock);
            }
        }
    private:
        static void* ThreadRoutine(void* args)
        {
            pthread_detach(pthread_self());
            //每一个线程都将执行相关的任务
            ThreadData* td=static_cast<ThreadData*>(args);
            td->_server->Execute(td->_sock);
            close(td->_sock);
            return nullptr;
        }
        int _serversock;
        Sock _sock;
        std::vector<func_t>_funcs;
    };
}
